package main

import (
	"fmt"
	"golang.org/x/sys/windows/registry"
	"io"
	"os"
	"path/filepath"
	"strconv"
	"syscall"
	"unsafe"
)



func main() {
	args := os.Args
	if len(args) == 1 { // 安装程序
		install()
	} else {
		var size = 8
		if len(args) >= 3 {
			size,_ = strconv.Atoi(args[2])
		}
		actionDelete(args[1], size)
	}
}

var workPath = "C:\\Program Files\\delete_file"
var exePath = workPath + "\\delete.exe"
func install()  {

	/**
	添加注册表
	文件夹上     HKEY_CLASSES_ROOT\directory\shell
	资源管理器   HKEY_CLASSES_ROOT\Directory\Background\shell
	*/

	setRegedit(registry.CLASSES_ROOT, "directory\\shell")
	setRegedit(registry.CLASSES_ROOT, "Directory\\Background\\shell")

	// 复制文件
	os.Mkdir(workPath, os.ModePerm)
	copyFile(os.Args[0], exePath)

	ShowMessage2("OK", "安装成功！")
}

func copyFile(srcName string, dstName string)  {
	src, err := os.Open(srcName)
	if err != nil {
		// 复制错误
		ShowMessage2("打开文件错误", err.Error())
		os.Exit(0)
	}
	defer src.Close()

	dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		ShowMessage2("打开文件错误", err.Error())
		os.Exit(0)
	}
	defer dst.Close()

	_, err = io.Copy(dst, src)
	if err != nil {
		ShowMessage2("复制文件错误", err.Error())
		os.Exit(0)
	}
}

func setRegedit(k registry.Key, path string)  {

	key, _, err := registry.CreateKey(k, path, registry.ALL_ACCESS)
	defer key.Close()
	fmt.Println(err)

	subKey, _, err := registry.CreateKey(key, "delete_file", registry.ALL_ACCESS)

	if err != nil {
		ShowMessage2("没有权限", "请已管理身份打开！")
		os.Exit(0)
	}
	subKey.SetStringValue("MUIVerb", "删除文件夹")
	subKey.SetExpandStringValue("Icon", exePath)
	defer subKey.Close()

	commandKey, _, _ := registry.CreateKey(subKey, "command", registry.ALL_ACCESS)
	commandKey.SetStringValue("", exePath +" \"%V\"")
	defer commandKey.Close()
}

func IntPtr(n int) uintptr {
	return uintptr(n)
}
func StrPtr(s string) uintptr {
	u16,_ := syscall.UTF16PtrFromString(s)
	return uintptr(unsafe.Pointer(u16))
}

// ShowMessage2 windows下的另一种DLL方法调用
func ShowMessage2(title, text string) {
	user32dll, _ := syscall.LoadLibrary("user32.dll")
	user32 := syscall.NewLazyDLL("user32.dll")
	MessageBoxW := user32.NewProc("MessageBoxW")
	MessageBoxW.Call(IntPtr(0), StrPtr(text), StrPtr(title), IntPtr(0))
	defer syscall.FreeLibrary(user32dll)
}







/**
开始删除
 */
func actionDelete(rootPath string, size int)  {
	//两个channel，一个用来放置工作项，一个用来存放处理结果。
	jobs := make(chan string, 100)
	results := make(chan string, 100)

	// 开启三个线程，也就是说线程池中只有3个线程，实际情况下，我们可以根据需要动态增加或减少线程。
	for w := 1; w <= size; w++ {
		go worker(w, jobs, results)
	}

	filepaths, _ := filepath.Glob(rootPath)
	for _,file := range filepaths {
		fmt.Println(file)
		jobs <- file
	}
	close(jobs)

	for a := 1; a <= len(filepaths); a++ {
		<-results
	}
}

//这个是工作线程，处理具体的业务逻辑，将jobs中的任务取出，处理后将处理结果放置在results中。
func worker(id int, jobs <-chan string, results chan<- string) {
	for file := range jobs {
		os.RemoveAll(file)
		results <- file
		fmt.Println("sadasdsads")
	}
}


